/**
 * 
 */
package de.htwg.ppt2html5.export;


import java.util.List;
import java.util.Map.Entry;

import org.pptx4j.pml.Presentation.SldSz;
import org.pptx4j.pml.STPlaceholderType;
import org.pptx4j.pml.Shape;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.htwg.ppt2html5.extraction.Interpreter;
import de.htwg.ppt2html5.extraction.Slide;


/**
 * this class builds an HTML file supported by a javascript and CSS3 file
 * 
 * @author Roman Allenov
 */
public class HTMLBuilder implements IHTMLBuilder {

   private static Logger log = LoggerFactory.getLogger(Interpreter.class);

   private String        doc = "";


   public HTMLBuilder() {

   }


   /**
    * this method invokes the HTML building process.
    * 
    * @param slideList
    *        - the slides Map
    */
   public String buildHTML(List<Slide> slideList,
                           String presTitle,
                           SldSz slideSize,
                           String alignment)
   {
      return createDoc(slideList, presTitle, slideSize, alignment);
   }


   /**
    * this method builds first HTML elements and invokes sections building, see
    * createSlideSections()
    * 
    * @param slideList
    * @param presTitle
    * @param slideSize
    * @param alignment
    * @return
    */
   private String createDoc(List<Slide> slideList,
                            String presTitle,
                            SldSz slideSize,
                            String alignment)
   {

      //@formatter:off
      doc    += "<!DOCTYPE html>" 
             + "\n<html>" 
             + "\n\t<head>"
             + "\n\t\t<meta charset=\"ISO-8859-1\">" 
             + "\n\t\t<title>" + presTitle + "</title>"
             + "\n\t\t<link rel=\"stylesheet\" href=\"css/reveal.css\">"
             + "\n\t\t<link rel=\"stylesheet\" href=\"css/default.css\" id=\"theme\">"
             + "\n\t\t<script src=\"js/reveal.js\"></script>"
             + "\n\t</head>"
             + "\n\t<body>"
             + "\n\t\t<div class=\"reveal\">"
             + "\n\t\t\t<div class=\"slides\">";
      doc    += createSlideSections(slideList, alignment);
      doc    += "\n\t\t\t</div>"
             + "\n\t\t</div>";
      doc    += addRevealConfig();
      doc    += "\n\t</body>" 
             + "\n</html>";

      //@formatter:on
      return doc;

   }


   /**
    * the config needed for Reaveal.js
    * 
    * @return
    */
   private String addRevealConfig()
   {
//@formatter:off
      String conf = "\n\t\t\t<script>"

                    + "\n\t\t\t\t// Full list of configuration options available at:"
                    + "\n\t\t\t\t// https://github.com/hakimel/reveal.js#configuration"
                    + "\n\t\t\t\tReveal.initialize({"
                    + "\n\t\t\t\t\tcontrols: true,"
                    + "\n\t\t\t\t\tprogress: true,"
                    + "\n\t\t\t\t\thistory: true,"
                    + "\n\t\t\t\t\tcenter: true,"

                    + "\n\t\t\t\t\ttheme: Reveal.getQueryHash().theme, // available themes are in /css/theme"
                    + "\n\t\t\t\t\ttransition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none+"
            // Parallax scrolling
            // parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
            // parallaxBackgroundSize: '2100px 900px',

            // Optional libraries used to extend on reveal.js
            /*dependencies: [
               { src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
               { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
               { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
               { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
               { src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
               { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
            ]*/
               //@formatter:on
                    + "\n\t\t\t\t});"

                    + "\n\t\t\t</script>";
      return conf;
   }


   /**
    * this method creates a &ltsection&gt element for each slide in the given slidesMap
    * 
    * @param slideList
    *        - the slides map
    * @param alignment
    *        - the alignment of the presentation transition to be horizontal or vertical
    * @return A String containing sections for each slide
    */
   private String createSlideSections(List<Slide> slideList, String alignment)
   {
      String slideSections = "";

      /**
       * if alignment chosen is vertical, enclose slide sections with another section. see
       * reveal.js for more information about nested slides
       */
      if (alignment.equals("vertikal")) {
         slideSections += "\n\t\t\t\t<section>";
      }

      /**
       * SLIDE SECTIONS <br>
       * if alignment is horizontal, build each slide in a simple section
       */
      for (Slide slide : slideList) {
         slideSections += "\n\t\t\t\t<section>";

         if (!slide.getCtrTitle().isEmpty()) {
            slideSections += "\n\t\t\t\t\t<h1 id=\"" + STPlaceholderType.CTR_TITLE.value()
                             + "\">" + slide.getCtrTitle() + "</h1>";
            if (!slide.getSubTitle().isEmpty()) {
               slideSections += "\n\t\t\t\t\t<h2 id=\"" + STPlaceholderType.SUB_TITLE.value()
                                + "\">" + slide.getSubTitle() + "</h2>";
            }
         }
         else if (!slide.getSlideTitle().isEmpty()) {
            slideSections += "\n\t\t\t\t\t<h1 class=\"" + STPlaceholderType.TITLE.value()
                             + "\">" + slide.getSlideTitle() + "</h1>";
         }
         // || !slide.getShapes().isEmpty()
         // || !slide.getConnectors().isEmpty() || !slide.getGraphFrames().isEmpty()
         // || !slide.getPics().isEmpty() || !slide.getRelations().isEmpty())
         if (!slide.getphShapes().isEmpty()) {
            for (Entry<String, Shape> shape : slide.getphShapes().entrySet()) {
               slideSections += "\n\t\t\t\t\t<div id=\"" + shape.getKey() + "\"></div>";
            }
         }

         // close section element
         slideSections += "\n\t\t\t\t</section>";

      }
      // closing element if alignment was "vertikal"
      if (alignment.equals("vertikal")) {
         slideSections += "\n\t\t\t\t</section>";
      }
      return slideSections;
   }
}
